<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"
    />
    <meta
      name="description"
      content="Demonstration of Polylines On Terrain via the Primitive API."
    />
    <meta name="cesium-sandcastle-labels" content="Development" />
    <title>Cesium Demo</title>
    <script type="text/javascript" src="../Sandcastle-header.js"></script>
    <script
      type="text/javascript"
      src="../../../Build/CesiumUnminified/Cesium.js"
      nomodule
    ></script>
    <script type="module" src="../load-cesium-es6.js"></script>
  </head>
  <body
    class="sandcastle-loading"
    data-sandcastle-bucket="bucket-requirejs.html"
  >
    <style>
      @import url(../templates/bucket.css);
    </style>
    <div id="cesiumContainer" class="fullSize"></div>
    <div id="loadingOverlay"><h1>Loading...</h1></div>
    <div id="toolbar">
      <table>
        <tbody>
          <tr>
            <td>Width</td>
            <td>
              <input
                type="range"
                min="1.0"
                max="32.0"
                step="1.0"
                data-bind="value: lineWidth, valueUpdate: 'input'"
              />
              <input type="text" size="5" data-bind="value: lineWidth" />
            </td>
          </tr>
        </tbody>
      </table>
    </div>
    <script id="cesium_sandcastle_script">
      function startup(Cesium) {
        "use strict";
        //Sandcastle_Begin
        var worldTerrain = Cesium.createWorldTerrain({
          requestWaterMask: true,
          requestVertexNormals: true,
        });

        var viewer = new Cesium.Viewer("cesiumContainer", {
          terrainProvider: worldTerrain,
        });

        if (!Cesium.GroundPolylinePrimitive.isSupported(viewer.scene)) {
          window.alert(
            "Polylines on terrain are not supported on this platform."
          );
        }

        var polylineIds = ["polyline1", "polyline2"];
        var groundPrimitiveId = "ground primitive";
        var selectedId = polylineIds[0];
        var polylineOnTerrainPrimitive;
        var groundPrimitiveOnTop = false;

        var lineWidth = 4.0;
        var viewModel = {
          lineWidth: lineWidth,
        };

        Cesium.knockout.track(viewModel);

        var toolbar = document.getElementById("toolbar");
        Cesium.knockout.applyBindings(viewModel, toolbar);

        Cesium.knockout
          .getObservable(viewModel, "lineWidth")
          .subscribe(function (newValue) {
            lineWidth = parseFloat(viewModel.lineWidth);
            if (Cesium.defined(selectedId)) {
              var attributes = polylineOnTerrainPrimitive.getGeometryInstanceAttributes(
                selectedId
              );
              lineWidth = parseFloat(viewModel.lineWidth);
              attributes.width = [lineWidth];
            }
          });

        var scene = viewer.scene;

        // Add a Rectangle GroundPrimitive to demonstrate Z-indexing with GroundPrimitives
        var rectangleGroundPrimitive = scene.groundPrimitives.add(
          new Cesium.GroundPrimitive({
            geometryInstances: new Cesium.GeometryInstance({
              geometry: new Cesium.RectangleGeometry({
                rectangle: Cesium.Rectangle.fromDegrees(
                  -112.1340164450331,
                  36.05494287836128,
                  -112.0840164450331,
                  36.10494287836128
                ),
                vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
              }),
              id: groundPrimitiveId,
            }),
            appearance: new Cesium.EllipsoidSurfaceAppearance({
              aboveGround: false,
              material: Cesium.Material.fromType("Color"),
            }),
            classificationType: Cesium.ClassificationType.TERRAIN,
          })
        );

        var leftHandler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
        leftHandler.setInputAction(function (movement) {
          var pickedObject = viewer.scene.pick(movement.position);
          if (Cesium.defined(pickedObject)) {
            console.log(pickedObject.id);
            // If picked the ground primitive, don't do anything
            if (pickedObject.id !== groundPrimitiveId) {
              selectedId = pickedObject.id;

              // Sync line width in toolbar with selected
              var attributes = polylineOnTerrainPrimitive.getGeometryInstanceAttributes(
                selectedId
              );
              viewModel.lineWidth = attributes.width[0];
            }
          } else {
            selectedId = undefined;
          }
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

        var polylinePositions = Cesium.Cartesian3.fromDegreesArray([
          -112.1340164450331,
          36.05494287836128,
          -112.08821010582645,
          36.097804071380715,
          -112.13296079730024,
          36.168769146801104,
          -112.10828895143331,
          36.20031318533197,
          -112.138548165717,
          36.1691100215289, // hairpins
          -112.11482556496543,
          36.20127524083297,
          -112.15921333464016,
          36.17876011207708,
          -112.14700151155604,
          36.21683132404626,
          -112.20919883052926,
          36.19475754001766,
        ]);

        var loopPositions = Cesium.Cartesian3.fromDegreesArray([
          -111.94500779274114,
          36.27638678884143,
          -111.90983004392696,
          36.07985366173454,
          -111.80360100637773,
          36.13694878292542,
          -111.85510122419183,
          36.26029588763386,
          -111.69141601804614,
          36.05128770351902,
        ]);

        function createPolylines(debugShowShadowVolume) {
          var instance1 = new Cesium.GeometryInstance({
            geometry: new Cesium.GroundPolylineGeometry({
              positions: polylinePositions,
              loop: false,
              width: 4.0,
            }),
            id: polylineIds[0],
            attributes: {
              show: new Cesium.ShowGeometryInstanceAttribute(),
              color: Cesium.ColorGeometryInstanceAttribute.fromColor(
                Cesium.Color.fromCssColorString("green").withAlpha(0.7)
              ),
            },
          });

          var instance2 = new Cesium.GeometryInstance({
            geometry: new Cesium.GroundPolylineGeometry({
              positions: loopPositions,
              loop: true,
              width: 8.0,
            }),
            id: polylineIds[1],
            attributes: {
              show: new Cesium.ShowGeometryInstanceAttribute(),
              color: Cesium.ColorGeometryInstanceAttribute.fromColor(
                Cesium.Color.fromCssColorString("#67ADDF").withAlpha(0.7)
              ),
            },
          });

          polylineOnTerrainPrimitive = new Cesium.GroundPolylinePrimitive({
            geometryInstances: [instance1, instance2],
            debugShowShadowVolume: debugShowShadowVolume,
          });
          scene.groundPrimitives.add(polylineOnTerrainPrimitive);
        }

        function applyPerInstanceColor() {
          polylineOnTerrainPrimitive.appearance = new Cesium.PolylineColorAppearance();
        }
        function applyColorMaterial() {
          polylineOnTerrainPrimitive.appearance = new Cesium.PolylineMaterialAppearance(
            {
              material: Cesium.Material.fromType("Color", {
                color: new Cesium.Color(0.7, 0.0, 1.0, 1.0),
              }),
            }
          );
        }
        function applyGlowMaterial() {
          polylineOnTerrainPrimitive.appearance = new Cesium.PolylineMaterialAppearance(
            {
              material: Cesium.Material.fromType("PolylineGlow", {
                innerWidth: 1.0,
              }),
            }
          );
        }
        function applyArrow() {
          polylineOnTerrainPrimitive.appearance = new Cesium.PolylineMaterialAppearance(
            {
              material: Cesium.Material.fromType("PolylineArrow"),
            }
          );
        }
        function applyDash() {
          polylineOnTerrainPrimitive.appearance = new Cesium.PolylineMaterialAppearance(
            {
              material: Cesium.Material.fromType("PolylineDash", {
                color: Cesium.Color.YELLOW,
              }),
            }
          );
        }
        function applyOutline() {
          polylineOnTerrainPrimitive.appearance = new Cesium.PolylineMaterialAppearance(
            {
              material: Cesium.Material.fromType("PolylineOutline"),
            }
          );
        }

        Sandcastle.addToolbarButton("Toggle instance show", function () {
          if (Cesium.defined(selectedId)) {
            var attributes = polylineOnTerrainPrimitive.getGeometryInstanceAttributes(
              selectedId
            );
            attributes.show = [attributes.show[0] ? 0 : 1];
          }
        });

        Sandcastle.addToolbarButton("Show all", function () {
          if (Cesium.defined(selectedId)) {
            var attributes = polylineOnTerrainPrimitive.getGeometryInstanceAttributes(
              "polyline1"
            );
            attributes.show = [1];
            attributes = polylineOnTerrainPrimitive.getGeometryInstanceAttributes(
              "polyline2"
            );
            attributes.show = [1];
          }
        });

        Sandcastle.addToolbarButton(
          "Toggle debugShowShadowVolume",
          function () {
            var debugShowShadowVolume = !polylineOnTerrainPrimitive.debugShowShadowVolume;
            var appearance = polylineOnTerrainPrimitive.appearance;
            scene.groundPrimitives.remove(polylineOnTerrainPrimitive);
            createPolylines(debugShowShadowVolume);
            polylineOnTerrainPrimitive.appearance = appearance;
          }
        );

        Sandcastle.addToolbarButton("Toggle z-index", function () {
          if (groundPrimitiveOnTop) {
            scene.groundPrimitives.raiseToTop(polylineOnTerrainPrimitive);
          } else {
            scene.groundPrimitives.lowerToBottom(polylineOnTerrainPrimitive);
          }
          groundPrimitiveOnTop = !groundPrimitiveOnTop;
        });

        function lookAt() {
          viewer.camera.lookAt(
            polylinePositions[1],
            new Cesium.Cartesian3(50000.0, 50000.0, 50000.0)
          );
          viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY);
        }

        Sandcastle.addToolbarButton("reset view", function () {
          lookAt();
        });

        createPolylines(false);
        applyPerInstanceColor();

        lookAt();

        Sandcastle.addToolbarMenu([
          {
            text: "Per Instance Color",
            onselect: function () {
              applyPerInstanceColor();
              Sandcastle.highlight(applyPerInstanceColor);
            },
          },
          {
            text: "Color",
            onselect: function () {
              applyColorMaterial();
              Sandcastle.highlight(applyColorMaterial);
            },
          },
          {
            text: "Glow",
            onselect: function () {
              applyGlowMaterial();
              Sandcastle.highlight(applyGlowMaterial);
            },
          },
          {
            text: "Arrow",
            onselect: function () {
              applyArrow();
              Sandcastle.highlight(applyArrow);
            },
          },
          {
            text: "Dash",
            onselect: function () {
              applyDash();
              Sandcastle.highlight(applyDash);
            },
          },
          {
            text: "Outline",
            onselect: function () {
              applyOutline();
              Sandcastle.highlight(applyOutline);
            },
          },
        ]);

        //Sandcastle_End
        Sandcastle.finishedLoading();
      }
      if (typeof Cesium !== "undefined") {
        window.startupCalled = true;
        startup(Cesium);
      }
    </script>
  </body>
</html>
